package com.rtsapp.server.domain.utils;

import com.rtsapp.server.common.ByteBuffer;
import com.rtsapp.server.common.IByteBufferSerializable;
import com.rtsapp.server.domain.IEntity;

import java.util.Collection;
import java.util.Iterator;
import java.util.concurrent.CopyOnWriteArrayList;

/**
 *
 * 嵌入的List属性
 *
 * TODO  使用 IByteBufferSerializable作为T类型的实现并未完成（它是关联实体的VO，构造方法一般有实体作为参数）
 */
public class EmbedListProperty<T>  {

    private final IEntity entity;
    private final CopyOnWriteArrayList<T> innerList = new CopyOnWriteArrayList<>( );
    private final Class<T> valueClass;

    public EmbedListProperty(IEntity entity, Class<T> valueClass ){
        this.entity = entity;
        this.valueClass = valueClass;
    }



    public int size() {
        return innerList.size();
    }

    public boolean isEmpty() {
        return innerList.isEmpty();
    }

    public boolean contains(Object o) {
        return innerList.contains( o );
    }

    public boolean add(T t) {
        boolean isAdd =  innerList.add( t );
        if( isAdd ){
            entity.setDirty();
        }
        return isAdd;
    }

    public<E extends T> void addAll(Collection<E> c) {
        if (c == null) {
            return;
        }

        for (E e : c) {
            this.add(e);
        }
    }
    public<E extends T> void addAll(EmbedListProperty<E> c) {
        if (c == null) {
            return;
        }

        for (int i = 0, count = c.size(); i < count; i++) {
            this.add(c.get(i));
        }
    }

    public T set( int index , T element ){
        entity.setDirty();
        return innerList.set( index, element );
    }

    public T remove( int index ) {
        T t = innerList.remove(index);
        if ( t != null ) {
            entity.setDirty();
        }
        return t;
    }

    public boolean remove(Object o) {
        boolean hasObj =   innerList.remove(o);
        if( hasObj ){
            entity.setDirty();;
        }
        return hasObj;
    }

    public T get( int index ){
        return innerList.get( index );
    }

    public void clear() {
        if( innerList.size() > 0 ) {
            innerList.clear();
            entity.setDirty();
        }
    }

    
    /**
     * 获得迭代器, 只能读, 不能修改
     * @return
     */
    public Iterator<T> iterator(){
        return innerList.iterator();
    }



    /**
     * 使用默认的方式序列化为bytes
     * @return
     */
    public byte[] getBytes( ) {

        ByteBuffer buffer = new ByteBuffer();

        buffer.writeInt(0);

        int count = 0; //由于多线程换将，map的大小可能再运行中被改变，因此用count来记数
        for ( Iterator<T> it = iterator( ); it.hasNext(); ) {

            count++;

            T value = it.next();

            if (value instanceof IByteBufferSerializable) {
                ((IByteBufferSerializable) (value)).writeToBuffer(buffer);
            } else {
                BytesSerializableUtils.write(buffer, value);
            }
        }

        buffer.setInt(0, count );
        return buffer.toBytes();
    }

    /**
     * 使用默认的方式进行反序列化
     * @param bytes
     */
    public void setBytes(  byte[] bytes) {

        this.clear();

        //bytes不能为空, 且长度大于整数
        if( bytes == null || bytes.length < 4 ){
            return;
        }

        try {
            ByteBuffer buffer = new ByteBuffer(bytes);
            int count = buffer.readInt();
            for (int i = 0; i < count; i++) {

                T value = null;
                if ( IByteBufferSerializable.class.isAssignableFrom( valueClass ) ) {
                    value = (T) valueClass.newInstance();
                    ((IByteBufferSerializable)value).readFromBuffer( buffer );
                } else {
                    value = BytesSerializableUtils.read(buffer, valueClass);
                }

                this.add( value );
            }

        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
    }

}
